// Copyright 2019-2021 Hackware SpA <human@hackware.cl>
// This file is part of "Hackware Userland" and licensed under the terms
// of the GNU Affero General Public License version 3, or (at your option)
// a later version. You should have received a copy of this license along
// with the software. If not, see <https://www.gnu.org/licenses/>.

import Vue from 'vue';
import Router from 'vue-router';

Vue.use(Router);

const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      redirect: { name: 'wallet' },
    },
    {
      path: '/login',
      component: () => import('./views/Login.vue'),
      children: [
        {
          path: '',
          component: () => import('./views/LoginByPassword.vue'),
          name: 'login-by-password',
        },
        {
          path: 'email',
          name: 'login-by-email',
          component: () => import('./views/LoginByEmail.vue'),
        },
      ],
    },
    {
      path: '/add-funds',
      component: () => import('./views/AddFunds.vue'),
      children: [
        {
          path: '',
          component: () => import('./views/AddFundsPayment.vue'),
          name: 'add-funds-payment',
        },
        {
          path: 'verify',
          name: 'add-funds-verify',
          component: () => import('./views/AddFundsVerify.vue'),
        },
        {
          path: ':gateway',
          name: 'add-funds-gateway',
          component: () => import('./views/AddFundsGateway.vue'),
        },
      ],
    },
    {
      path: '/transactions',
      name: 'transactions',
      component: () => import('./views/Transactions.vue'),
    },
    {
      path: '/wallet',
      name: 'wallet',
      component: () => import('./views/Wallet.vue'),
    },
  ],
});

router.beforeEach((to, from, next) => {
  const { $auth } = router.app;

  if ($auth.isLoggedIn() || ['login-by-email', 'login-by-password'].includes(to.name)) {
    next();
  } else {
    router.app.$nextTick(() => {
      const app = router.app.$children[0]; // App.vue, is this too hacky?
      const authToken = ('auth_token' in to.query) ? to.query.auth_token : null;

      $auth.fetchUser(authToken, false)
        .then((response) => {
          if ([401, 403].includes(response.status)) {
            app.showSidebar = false;
            next({ name: 'login-by-password' });
            throw new Error(`${response.statusText} request to ${response.url}`);
          }
          return response.json();
        })
        .then((body) => {
          if ('error' in body) {
            next({ name: 'login-by-password' });
            throw new Error(body.error.message);
          }

          $auth.setUser(body);
          app.initSidebar();
          if ('redirect_to' in to.query) {
            window.location.replace(to.query.redirect_to);
          } else {
            next();
          }
        });
    });
  }
});

export default router;
